#include "exchange_dxf.h"

#include "common/system_log.h"
#include "ExchangeIO.h"
#include "utils/file_util.h"
#include <memory>
#include <vector>
#include "utils/string_util.h"

#ifdef AMCAX_DXF_ENABLE
#include "DXFWriter.h"
#endif
#include "ExchangeTopoShape.h"

AMCAX_EXCHANGE_NAMESPACE_BEGIN

#ifdef AMCAX_DXF_ENABLE
void ExchangeDxf::read_common(AMCAX::DXFReader &reader)
{
    DxfInputParameter *parameter = dynamic_cast<DxfInputParameter *>(GetExchangeParameter()) ;
    if (nullptr != parameter) {
        std::vector<std::string> layers = parameter->GetLayers();
        if (layers.size() > 0) {
            reader.SetFixLayers(layers);
        }
    }
    std::vector<AMCAX::DXFShape> dxf_shapes ;
    reader.ReadShape(dxf_shapes);
    for (auto dxf_shape_item: dxf_shapes) {
        if (dxf_shape_item.Shape.IsNull()) {
            continue;
        }
        std::shared_ptr<ExchangeObject> exshape(new ExchangeObject(string_util::generate_UUID()));
        exshape->shape = std::make_shared<ExchangeTopoShape>(dxf_shape_item.Shape);
        exshape->name = dxf_shape_item.Name;
        exchangeObjectList_.push_back(exshape);
    }
}
#endif

void ExchangeDxf::ReadFromFilePath()
{
#ifdef AMCAX_DXF_ENABLE
    if (!AMCAX::Exchange::file_util::is_file_exist(filePath_)) {
        LOG_ERROR("file not exist:{}",filePath_) ;
        return ;
    }
    AMCAX::DXFReader reader(filePath_) ;
    read_common(reader);
#endif
}

void ExchangeDxf::ReadFromFileStream()
{
#ifdef AMCAX_DXF_ENABLE
    if(nullptr == inFileStream_) {
        LOG_ERROR("inFileStream_ is null") ;
        return  ;
    }
    AMCAX::DXFReader reader(inFileStream_) ;
    read_common(reader);
#endif
}


#ifdef AMCAX_DXF_ENABLE
void from_exchange_to_dxf(std::shared_ptr<ExchangeObject> exchange_shape,std::vector<std::shared_ptr<AMCAX::DXFShape>>& dxf_shape_vector)
{
    if (exchange_shape->childs.size() > 0)
    {
        for(auto& exchange_chlid_shape : exchange_shape->childs)
        {
            std::shared_ptr<AMCAX::DXFShape> dxf_shape(new AMCAX::DXFShape(exchange_chlid_shape->shape->GetShape(), exchange_chlid_shape->name)) ;
            dxf_shape_vector.push_back(dxf_shape);
            from_exchange_to_dxf(exchange_chlid_shape,dxf_shape_vector);
        }
    }
}
#endif

void ExchangeDxf::Write(const std::vector<std::shared_ptr<ExchangeObject>>& exchange_shapes, const std::shared_ptr<ExchangeDocumentInstance> &exchangeDocumentInstance)
{
#ifdef AMCAX_DXF_ENABLE
    std::unique_ptr<AMCAX::DXFWriter> work_ptr ;
    
    if (OUTPUT_FILE_TYPE::FILE_PATH == outputFileType_) {
        if (AMCAX::Exchange::file_util::is_file_exist(filePath_))
        {
            LOG_ERROR("file<{}> already exist",filePath_) ;
            return ;
        }
        work_ptr.reset(new AMCAX::DXFWriter(filePath_)) ;
    }
    else if (OUTPUT_FILE_TYPE::FILE_OUTPUT_STREAM == outputFileType_) 
    {
        if(nullptr == outFileStream_) {
            LOG_ERROR("outFileStream_ is null") ;
            return  ;
        }
        work_ptr.reset(new AMCAX::DXFWriter(outFileStream_)) ;
    }else {
        LOG_ERROR("output file type:{} is unknown",(int)outputFileType_) ;
        return ;
    }
    // AMCAX::DXFWriter work(filePath_) ;
    work_ptr->Init() ;

    std::vector<std::shared_ptr<AMCAX::DXFShape>> dxf_data_vector ;
    for (auto &top_shape : exchange_shapes) {
        std::shared_ptr<AMCAX::DXFShape> dxf_shape(new AMCAX::DXFShape(top_shape->shape->GetShape(),top_shape->name)) ;
        dxf_data_vector.push_back(dxf_shape);
        from_exchange_to_dxf(top_shape,dxf_data_vector); 
    }

    std::vector<AMCAX::DXFShape> dxf_shapes ;
    for (auto &dxf_item : dxf_data_vector){
        AMCAX::DXFShape dxf_shape = *dxf_item ;
        dxf_shapes.push_back(dxf_shape) ;
    }
    
    work_ptr->WriteShape(dxf_shapes) ;
    work_ptr->Done() ;
#endif
}



AMCAX_EXCHANGE_NAMESPACE_END